﻿using System;
using System.IO;
using ExcelAutomator.Configuration;
using log4net;
using Microsoft.Office.Interop.Excel;

namespace ExcelAutomator
{
	public class ExecutionContext
	{
		public Application Application { get; private set; }
		public FileInfo InputFile { get; private set; }
		public FileInfo TargetFile { get; private set; }
		public SettingsConfiguration Configuration { get; private set; }
		private readonly IParameterPatternParser m_ParameterPatternParser;

		#region Ctor

		public ExecutionContext(Application application, FileInfo inputFile, FileInfo targetFile, SettingsConfiguration configuration, IParameterPatternParser parameterPatternParser)
		{
			Application = application;
			InputFile = inputFile;
			TargetFile = targetFile;
			m_ParameterPatternParser = parameterPatternParser;
			Configuration = configuration;
			ParseParamters(configuration);
		}
		#endregion

		#region ParseParamters

		private void ParseParamters(SettingsConfiguration configuration)
		{
			if (!configuration.FilenamePattern.IsNOE())
			{
				Configuration = m_ParameterPatternParser.Parse(configuration, this, new[]{typeof(ExcelParameterPatternResolverBase)});
			}
		}

		#endregion

		#region InputWorkbook

		private Workbook m_InputWorkbook;
		public Workbook InputWorkbook
		{
			get
			{
				if (m_InputWorkbook == null)
				{
					m_InputWorkbook = Application.OpenWorkbook(InputFile.FullName);
				}
				return m_InputWorkbook;
			}
		}
		#endregion

		#region TargetWorkbook

		private Workbook m_TargetWorkbook;
		public Workbook TargetWorkbook
		{
			get
			{
				if (InputFile.FullName.Equals(TargetFile.FullName))
				{
					return InputWorkbook;
				}
				if (m_TargetWorkbook == null)
				{
					m_TargetWorkbook = Application.OpenWorkbook(TargetFile.FullName);
				}
				return m_TargetWorkbook;
			}
			
		}

		#endregion

		public bool TryGetWorksheet(string value, ExecutionContextConfiguration context, out Worksheet worksheet)
		{
			if (context == ExecutionContextConfiguration.InputWorkbook)
			{
				return this.InputWorkbook.TryGetWorksheet(value, out worksheet);
			}

			if (context == ExecutionContextConfiguration.TargetWorkbook)
			{
				return this.TargetWorkbook.TryGetWorksheet(value, out worksheet);
			}

			worksheet = null;
			return false;
		}

		internal void Save()
		{
			//TODO save where it is, save in output dir, save with new filename, save in output dir with new filename
			string saveAsFilename = this.TargetFile.Name;
			string outputDir = this.TargetFile.Directory.FullName;

			if (Configuration.FilenamePattern == null && !Configuration.IsOutDirectoryDefined)
			{
				if (!TargetWorkbook.Saved)
				{
					Log.InfoFormat("Save target as: {0}",  TargetWorkbook.FullName);
					TargetWorkbook.Save();
				}
				return;
			}
			
			if (Configuration.IsOutDirectoryDefined)
			{
				if (!Path.IsPathRooted(Configuration.OutputFolder))
				{
					outputDir = Path.Combine(Environment.CurrentDirectory, Configuration.OutputFolder);
				}
				else
				{
					outputDir = Configuration.OutputFolder;
				}

				if (!Directory.Exists(outputDir))
				{
					Directory.CreateDirectory(outputDir);
				}
			}
			
			if (Configuration.FilenamePattern != null)
			{
				saveAsFilename = Configuration.FilenamePattern;
			}

			var newFileName = Path.Combine(outputDir, saveAsFilename);
			Log.InfoFormat("Save target as: {0}", newFileName);
			TargetWorkbook.SaveCopyAs(newFileName);
			
		}

		internal void Close()
		{
			TargetWorkbook.Close(false, Type.Missing, Type.Missing);
		}

		internal void SaveAndClose()
		{
			Save();
			Close();
		}

		private static ILog Log
		{
			get { return LogManager.GetLogger(typeof (ExecutionContext)); }
		}

	}
}
